package cn.hunqing.web.filter;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.hunqing.web.param.LoginParameters;
import cn.hunqing.web.util.PathConstants;
import cn.hunqing.web.util.SessionUtils;

public class SecurityFilter implements Filter {
	private static Logger logger = LoggerFactory.getLogger(SecurityFilter.class);

	private static final List<String> ESCAPED_URL_LIST = Arrays.asList(
			"resources", 
			"/cards/",
			PathConstants.PATH_RETRIEVE,
			PathConstants.PATH_REGISTER, 
			PathConstants.PATH_TEMPLATE_LIST, 
			PathConstants.PATH_WECHAT,
			PathConstants.PATH_INDEX);

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
			throws IOException, ServletException {
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		HttpServletResponse httpServletResponse = (HttpServletResponse) response;

		String path = getRequestPath(httpServletRequest);

		// escape resources, templates, cards, register, wechat request
		for(String escapedUrl:ESCAPED_URL_LIST){
			if(StringUtils.contains(path, escapedUrl)){
				filterChain.doFilter(httpServletRequest, httpServletResponse);
				return;
			}
		}

		boolean isLogin = SessionUtils.isLogin(httpServletRequest.getSession());
		// 如果是ajax请求响应头会有，x-requested-with；
		if (httpServletRequest.getHeader("x-requested-with") != null
				&& httpServletRequest.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest") && !isLogin) {
			// 在响应头设置session状态
			httpServletResponse.setHeader("sessionstatus", "timeout");
			response.getWriter().print("timeout");
			return;
		}

		if (StringUtils.contains(path, PathConstants.PATH_LOGIN) && isLogin) {
			logger.info("Access the " + getRequestPath(httpServletRequest) + ", but login. So redirect to index page");
			httpServletResponse.sendRedirect(PathConstants.PATH_ROOT + PathConstants.PATH_TEMPLATE_LIST+"/v2");
			return;
		}

		if ((StringUtils.contains(path, PathConstants.PATH_LOGIN) && !isLogin)) {
			filterChain.doFilter(httpServletRequest, httpServletResponse);
			return;
		}

		if (!isLogin) {
			logger.info(
					"Access the " + getRequestPath(httpServletRequest) + ", but not login. So redirect to log page");
			httpServletRequest.getSession().setAttribute(LoginParameters.REDRIECT_FROM, path);
			httpServletResponse.sendRedirect(PathConstants.PATH_ROOT + PathConstants.PATH_LOGIN);
			return;
		}
		filterChain.doFilter(httpServletRequest, httpServletResponse);
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	private String getRequestPath(HttpServletRequest request) {
		// String path = request.getHeader("referer");
		// if (StringUtils.isBlank(path))
		// path = request.getRequestURL().toString();

		return request.getRequestURL().toString();
	}
}
